package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.LogicException;
import cn.wolfcode.wolf2w.cache.service.IUserInfoRedisService;
import cn.wolfcode.wolf2w.cache.util.RedisKeys;
import cn.wolfcode.wolf2w.domain.UserInfo;
import cn.wolfcode.wolf2w.repository.UserInfoRepository;
import cn.wolfcode.wolf2w.service.IUserInfoService;
import cn.wolfcode.wolf2w.util.AssertUtil;
import cn.wolfcode.wolf2w.util.Consts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

@Service
//@Transactional mongodb的事务必须是复制集的方式
public class UserInfoServiceImpl implements IUserInfoService{
    @Autowired
    private UserInfoRepository repository;
    @Autowired
    private IUserInfoRedisService userInfoRedisService;

    @Override
    public void save(UserInfo userInfo) {
        userInfo.setId(null);//把id设置为null
        repository.save(userInfo);//存入userInfo对象

    }

    @Override
    public void update(UserInfo userInfo) {
        repository.save(userInfo);//编辑和保存是一样的,更新之后则要保存userInfo对象

    }

    @Override
    public void delete(String id) {
        repository.deleteById(id);

    }

    @Override
    public UserInfo get(String id) {
        //orEls,查询id,存在就返回,不承诺在就返回null
        return repository.findById(id).orElse(null);

    }

    @Override
    public List<UserInfo> list() {
        //查询所有
        return repository.findAll();
    }

    @Override
    public boolean checkPhone(String phone) {
        //findByPhone查询到我们的phone是否是空,
        // 如果有值,那么不等于空成立,则返回的是true,否则,是false
        UserInfo userInfo = repository.findByPhone(phone);
        return userInfo != null;
    }

    @Override
    public void sendVerifyCode(String phone, String smsUrl, String appKey) {
        //1.创建验证码,编辑短信
        //其中UUID可能会创建出一个-,所以得去掉,因为相对应验证码中不可能出现-,substring这个表示是从哪一位的下标开始,截取几位数
        String code =  UUID.randomUUID().toString()
                .replaceAll("-","").substring(0,4);
        StringBuilder sb = new StringBuilder(80);//取出80个字符串左右就够了
        sb.append("您注册的验证码是").append(code).append(",请在")
                .append(Consts.VERIFY_CODE_VAI_TIME).append("分钟内使用");
        //2.发送短信:就是让java怎么发起http请求
        System.out.println(sb.toString());//假装发送短信
        //Url:https://way.jd.com/chuangxin/dxjk?mobile=13568813957&content=【创信】
        // 你的验证码是：5873，3分钟内有效！
        // &appkey=857561e0635432ad5319f8de828d5f8f
        //spring提供http请求发送类
        RestTemplate restTemplate = new RestTemplate();
        //参数1:请求url[url中有参数占位符]  ,参数2:返回值类型  参数3:请求你需要的参数
//        String ret = restTemplate.getForObject(smsUrl, String.class,
//                phone,"【创信】"+sb.toString(),appKey);
//        System.out.println(ret);
//        if (!ret.contains("Success")){
//            throw new LogicException("短信发送失败");
//        }

        //3.将验证码发送到缓存到Redis中去
        userInfoRedisService.sendVerifyCode(phone,code);
    }

    @Override
    public void regist(String phone, String nickname, String password, String rpassword, String verifyCode) {
        //判断参数是否为null
        //因为之前有许多重复的代码,所有把相同的操作抽到了一个util类中
        AssertUtil.hasLength(phone, "手机号码不能为空");
        AssertUtil.hasLength(nickname, "昵称不能为空");
        AssertUtil.hasLength(password, "密码不能为空");
        AssertUtil.hasLength(rpassword, "确认密码不能为空");
        AssertUtil.hasLength(verifyCode, "验证码不能为空");

        //判断密码是否为空
        AssertUtil.isEquals(password, rpassword, "两次输入密码不一致");

        //判断手机号码是否能符合格式
//        public static void isPhone(String phone) throws PatternSyntaxException {
//            String p ="^(13[0-9]|bai15[01]|153|15[6-9]|180|18[23]|18[5-9])\\d{8}$";
//            Pattern compile = Pattern.compile(p);
//            Matcher matcher = compile.matcher(phone);
//
//        }


        //判断手机号是否是唯一

        if (this.checkPhone(phone)) {
            throw new LogicException("手机号码已经被注册了");
        }
        // 判断验证码是否正确
        String code = userInfoRedisService.getVerifyCode(phone);
        //code==null :表示验证码失效.或者是 验证码没有发送过去
        //equalsIgnoreCase :表示忽略大小写的比较
        if (code == null || !code.equalsIgnoreCase(verifyCode)){
        throw new LogicException("手机号码已经被注册了");
        }
        //注册

        UserInfo userInfo = new UserInfo();

        userInfo.setNickname(nickname);
        userInfo.setPhone(phone);
        userInfo.setEmail("");
        userInfo.setPassword(password);  //假装已经加密
        userInfo.setGender(UserInfo.GENDER_SECRET);
        userInfo.setLevel(1);
        userInfo.setCity("");
        userInfo.setHeadImgUrl("/images/default.jpg");
        userInfo.setInfo("");
        //关键字建议大家自己控制
        userInfo.setState(UserInfo.STATE_NORMAL);  //明确写明状态


//        throw new LogicException("一个很恶心的系统异常");

        this.save(userInfo);



    }

    @Override
    public UserInfo login(String username, String password) {
        //1:password之前加密,此处需要加密
        //2:此处需要进行参数为null判断
        UserInfo user = repository.findByPhone(username);
        if (user == null || !password.equals(user.getPassword())){
            throw new LogicException("账号或密码错误");
        }
        return user;
    }

}
